// import * as Cesium from 'cesium'

let kyViewer = null
let distance = 0
let measureLabelPos = 0
let innerS = 0
// let timer = null

/**
 * 测量类
 * @author 阮景涛
 */
export default class Measure {
  /**
   * 构造函数
   * @param viewer
   * @param options
   */
  constructor(viewer, options = null) {
    this.viewer = viewer
    kyViewer = viewer
    this._init()
  }

  /**
   * 初始化参数
   * @private
   */
  _init() {
    // 存储位置数组
    this.positions = []
    // 测量的多边形线
    this.measurePoly = null
    // 测量距离
    this.measureDistance = 0
    // 当前笛卡尔空间坐标
    this.cartesian3 = null
    // 标签位置
    this.labelPt = null
    // 测量距离
    distance = 0
    // 测量标签位置
    measureLabelPos = 0
    // 单步距离
    innerS = 0
  }

  /**
   * 测量地形贴地距离
   */
  terrainDistanceSurface() {
    // viewer的鼠标左键点击事件
    this.viewer.onClick((target) => {
      // 获取当前鼠标所点击的元素
      const feature = this.viewer.scene.pick(target.position)
      if (feature instanceof Cesium.Cesium3DTileFeature) {
        console.log('点击了模型', feature)
        return
      }
      this.cartesian3 = this.viewer.scene.globe.pick(
        this.viewer.camera.getPickRay(target.position),
        this.viewer.scene
      )
      if (this.positions.length === 0) {
        this.positions.push(this.cartesian3.clone())
      }
      this.positions.push(this.cartesian3)
      this.labelPt = this.positions[this.positions.length - 1]
      // 如果此时位置数组长度大于2
      if (this.positions.length > 2) {
        this._getTerrainDistance(this.positions)
        // 如果长度等于2,添加一个起始点
      } else if (this.positions.length === 2) {
        // console.log('绘制起点')
        this.viewer.entities.add({
          name: '_range',
          id: 'range',
          position: this.labelPt,
          point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 2,
            clampToGround: true
          },
          label: {
            text: '起 点',
            font: 'normal 18px SimHei',
            fillColor: Cesium.Color.ORANGE, // 文本颜色
            backgroundColor: Cesium.Color.WHITE, // 背景色
            style: Cesium.LabelStyle.FILL, // 文本样式，轮廓
            outlineWidth: 2, // 轮廓宽度
            outlineColor: Cesium.Color.WHITE,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 圆点位置
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // 文本的位置
            pixelOffset: new Cesium.Cartesian2(0, -10), // 文本偏移量，Cartesian2
            clampToGround: true
          }
        })
      }
    })

    // viewer的鼠标移动事件
    this.viewer.onMove((target) => {
      // 获取当前鼠标所点击的元素
      const feature = this.viewer.scene.pick(target.endPosition)
      if (feature instanceof Cesium.Cesium3DTileFeature) {
        console.log('移动到模型', feature)
        return
      }
      if (this.positions.length >= 2) {
        this.cartesian3 = this.viewer.scene.globe.pick(
          this.viewer.camera.getPickRay(target.endPosition),
          this.viewer.scene
        )
        if (!Cesium.defined(this.measurePoly)) {
          this.measurePoly = new PolyLinePrimitive(this.positions)
        } else {
          this.positions.pop()
          this.positions.push(this.cartesian3)
        }
        // console.log('鼠标移动carte3 = ', this.cartesian3, this.positions)
      }
    })

    // viewer的鼠标右键点击事件
    this.viewer.onRightClick((target) => {
      // 获取当前鼠标所点击的元素
      const feature = this.viewer.scene.pick(target.position)
      if (feature instanceof Cesium.Cesium3DTileFeature) {
        console.log('点击了模型', feature)
        return
      }
      this.cartesian3 = this.viewer.scene.globe.pick(
        this.viewer.camera.getPickRay(target.position),
        this.viewer.scene
      )
      if (this.positions.length === 0) {
        this.positions.push(this.cartesian3.clone())
      }
      this.positions.push(this.cartesian3)
      this.labelPt = this.positions[this.positions.length - 1]
      // console.log('鼠标左键双击positions = ', this.cartesian3, this.positions)
      if (this.positions.length > 2) {
        this._getTerrainDistance(this.positions)
      } else if (this.positions.length === 2) {
        // 三维场景中添加label
        this.viewer.entities.add({
          name: '_range',
          position: this.labelPt,
          point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color,
            outlineWidth: 2,
            clampToGround: true
          }
        })
      }
      this.viewer.destroyHandler()
    })
    // viewer鼠标右键点击事件
    this.viewer.onLeftDoubleClick((target) => {
      this.viewer.destroyHandler()
      this._removeEntities()
      this._init()
    })
  }

  /**
   * 取消测量
   */
  quitMeasure() {
    this._removeEntities()
    this._init()
  }

  /**
   * 空间距离
   */
  terrainDistanceSpace() {
  }

  /**
   * 测量模型的贴地距离
   */
  modelDistanceSurface() {
    // viewer的鼠标左键点击事件
    this.viewer.onClick((target) => {
      // 获取当前鼠标所点击的元素
      const feature = this.viewer.scene.pick(target.position)
      if (feature === undefined) {
        console.log('点击了非模型', feature)
        return
      }
      // 获取点击模型位置的坐标,有高度
      this.cartesian3 = this.viewer.scene.pickPosition(target.position)
      const carto = Cesium.Cartographic.fromCartesian(this.cartesian3)
      const lng = Cesium.Math.toDegrees(carto.longitude)
      const lat = Cesium.Math.toDegrees(carto.latitude)
      console.log('经纬高:', lng, lat, carto.height)
      if (this.positions.length === 0) {
        this.positions.push(this.cartesian3.clone())
      }
      this.positions.push(this.cartesian3)
      this.labelPt = this.positions[this.positions.length - 1]
      // 如果此时位置数组长度大于2
      if (this.positions.length > 2) {
        this._getSpaceDistance(this.positions)
        // 如果长度等于2,添加一个起始点
      } else if (this.positions.length === 2) {
        // console.log('绘制起点')
        this.viewer.entities.add({
          name: '_range',
          id: 'range',
          position: this.labelPt,
          point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 2,
            clampToGround: true
          },
          label: {
            text: '起 点',
            font: 'normal 18px SimHei',
            fillColor: Cesium.Color.ORANGE, // 文本颜色
            backgroundColor: Cesium.Color.WHITE, // 背景色
            style: Cesium.LabelStyle.FILL, // 文本样式，轮廓
            outlineWidth: 2, // 轮廓宽度
            outlineColor: Cesium.Color.WHITE,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 圆点位置
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // 文本的位置
            pixelOffset: new Cesium.Cartesian2(0, -10), // 文本偏移量，Cartesian2
            clampToGround: true
          }
        })
      }
    })

    // viewer的鼠标移动事件
    this.viewer.onMove((target) => {
      // 获取当前鼠标所点击的元素
      const feature = this.viewer.scene.pick(target.endPosition)
      if (feature === undefined) {
        console.log('移动到非模型', feature)
        return
      }
      if (this.positions.length >= 2) {
        // 获取点击的模型的位置,有高度
        this.cartesian3 = this.viewer.scene.pickPosition(target.endPosition)
        if (!Cesium.defined(this.measurePoly)) {
          this.measurePoly = new PolyLinePrimitive(this.positions)
        } else {
          this.positions.pop()
          this.positions.push(this.cartesian3)
        }
        // console.log('鼠标移动carte3 = ', this.cartesian3, this.positions)
      }
    })

    // viewer的鼠标右键点击事件
    this.viewer.onRightClick((target) => {
      // 获取当前鼠标所点击的元素
      const feature = this.viewer.scene.pick(target.position)
      if (feature === undefined) {
        console.log('点击了非模型', feature)
        return
      }
      this.cartesian3 = this.viewer.scene.pickPosition(target.position)
      if (this.positions.length === 0) {
        this.positions.push(this.cartesian3.clone())
      }
      this.positions.push(this.cartesian3)
      this.labelPt = this.positions[this.positions.length - 1]
      // console.log('鼠标左键双击positions = ', this.cartesian3, this.positions)
      if (this.positions.length > 2) {
        this._getSpaceDistance(this.positions)
      } else if (this.positions.length === 2) {
        // 三维场景中添加label
        this.viewer.entities.add({
          name: '_range',
          position: this.labelPt,
          point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color,
            outlineWidth: 2,
            clampToGround: true
          }
        })
      }
      this.viewer.destroyHandler()
    })
    // viewer鼠标右键点击事件
    this.viewer.onLeftDoubleClick((target) => {
      this._removeEntities()
      this._init()
    })
  }

  /**
   * 三角测量
   */
  heightTriangle() {
  }

  /**
   * 贴地计算距离的内部函数
   * @param poin1 点1
   * @param poin2 点2
   * @private
   */
  _getTerrainDistance (positions) {
    const i = positions.length - 3
    measureLabelPos = positions[positions.length - 1]
    const poin1 = Cesium.Cartographic.fromCartesian(positions[i])
    const poin2 = Cesium.Cartographic.fromCartesian(positions[i + 1])
    // debugger
    const geodesic = new Cesium.EllipsoidGeodesic()
    // console.log([poin1, poin2])
    geodesic.setEndPoints(poin1, poin2)
    const s = geodesic.surfaceDistance
    const cartoPts = [poin1]
    for (let i = 1000; i < s; i += 1000) {
      const cartoPt = geodesic.interpolateUsingSurfaceDistance(i)
      cartoPts.push(cartoPt)
    }
    cartoPts.push(poin2)
    // 返回两点之间的距离
    const promise = Cesium.sampleTerrain(this.viewer.terrainProvider, 2, cartoPts)
    // console.log('当前前后两点', cartoPts, '距离', promise)
    promise.then(function (updatedPositions) {
      for (let i = 0; i < updatedPositions.length - 1; i++) {
        const geoD = new Cesium.EllipsoidGeodesic()
        geoD.setEndPoints(updatedPositions[i], updatedPositions[i + 1])
        innerS = geoD.surfaceDistance
        innerS = Math.sqrt(Math.pow(innerS, 2) + Math.pow(updatedPositions[i + 1].height - updatedPositions[i].height, 2))
        distance += innerS
      }
      // console.log(distance, updatedPositions.length - 2, innerS)
      innerS += (updatedPositions.length - 2) * 1000
      // 在三维场景中添加 label
      const textDistance = (distance > 10000 ? (distance / 1000.0).toFixed(2) + '公里' : distance.toFixed(2) + '米') + `(+${innerS.toFixed(2)}米)`
      drawEntity(textDistance)
    })
  }

  /**
   * 计算空间距离的位置函数
   * @param positions 位置数组
   * @private
   */
  _getSpaceDistance(positions) {
    // 只算最后一截,与前面累加
    const i = positions.length - 3
    measureLabelPos = positions[positions.length - 1]
    innerS = Cesium.Cartesian3.distance(positions[i], positions[i + 1])
    distance += innerS
    const carto1 = Cesium.Cartographic.fromCartesian(positions[i])
    const carto2 = Cesium.Cartographic.fromCartesian(positions[i + 1])
    const heightDiff = carto2.height - carto1.height
    const textDistance = (distance > 10000 ? (distance / 1000.0).toFixed(2) + '公里' : distance.toFixed(2) + '米') + `(+${innerS.toFixed(2)}米,高度差:${heightDiff.toFixed(2)})`
    drawEntity(textDistance)
  }

  /**
   * 清除测量中出现的所有点和线进行下一次测量
   */
  _removeEntities() {
    const RangeArea = this.viewer.entities._entities._array
    for (let i = 0; i < RangeArea.length; i++) {
      if (RangeArea[i]._name === '_range') {
        this.viewer.entities.remove(RangeArea[i])
        i--
      }
    }
  }
}

const PolyLinePrimitive = (function () {
  function line (positions) {
    this.options = {
      name: '_range',
      polyline: {
        show: true,
        positions: [],
        material: Cesium.Color.CORNFLOWERBLUE,
        width: 3,
        clampToGround: false
      }
    }
    this.positions = positions
    this.init()
  }

  line.prototype.init = function () {
    const update = () => {
      return this.positions
    }
    // 实时更改线的位置，更新线
    this.options.polyline.positions = new Cesium.CallbackProperty(update, false)
    kyViewer.entities.add(this.options)
  }
  return line
})()

/**
 * 增加测量显示标签
 */
function drawEntity(textDisance) {
  kyViewer.entities.add({
    name: '_range',
    position: measureLabelPos,
    point: {
      poixeSize: 4,
      color: Cesium.Color.RED,
      outlineColor: Cesium.Color.MINTCREAM,
      outlineWidth: 2,
      clampToGround: true
    },
    label: {
      text: textDisance,
      font: '18px sans-serif',
      fillColor: Cesium.Color.GOLD,
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      outLineWidth: 2,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(0, -10),
      clampToGround: true
    }
  })
}
